#ifndef nat_traversal_h
#define nat_traversal_h

/*----------------- Data types definition-----------------*/

#define SERVER_PORT			61255
#define MAX_NO_CLIENTS		50000


/* Character device major */
#define NAT_TRAVERSAL_MAJOR	42

/* IOCTL commands	*/
#define IOCTL_SERVER_ADD_CLIENT		1
#define IOCTL_SERVER_DEL_CLIENT		2
#define	IOCTL_SERVER_ENABLE			10
#define IOCTL_SERVER_DISABLE		11
#define IOCTL_SERVER_GET_CLIENTS	3

/* Known commands in UDP packets */
#define REGISTER		1
#define UNREGISTER		2
#define REQUEST_DATA	3


/* Response codes*/
#define INVALID_ID				1
#define SERVER_FULL				2
#define NOT_REGISTERED			3
#define REGISTER_OK				4
#define REGISTER_NOT_OK			5
#define UNREGISTER_OK			6
#define UNREGISTER_NOT_OK		7
#define CLIENT_FOUND			8
#define CLIENT_NOT_FOUND		9
#define INVALID_COMMAND			10
#define GENERAL_ERROR			11


/* Structure that keeps client's data */
/** 
*      @privatePort:	client's communication port
*      @privateIP:		client's private IP
*      @publicPort:		client's public port
*      @publicIP:		client's public IP
*      @clientID:		client's registration ID
*      @list:			list header
*/
typedef struct ClientData {
	int privatePort;
	int privateIP;
	int publicPort;
	int publicIP;
	int clientID;
	struct list_head list;
} ClientData_t;


/* Data structure in UDP packet*/
/*
response[0] = publicPort
response[1] = publicIP
response[2] = privatePort
response[3] = privateIP
*/
typedef struct PacketData {
	int myPort;//port
	int myIP;//ip
	int myID;//id
	int command;
	int cmdArgs;//cmdArgs
	int responseCode;
	int response[4];
} PacketData_t;

typedef struct Details
{
	int realP, realIP, retCode;
	PacketData_t *packetData;
} Details_t;


struct NatTraversalDeviceData {
	struct cdev cdev;				//IOCTL ops
	struct list_head allClients;
	int clientNo;					//number of registered clients
	int enabled;					//Server enabled or not
	struct nf_hook_ops hook_in;
	spinlock_t mylock;
	struct work_struct my_work;
	Details_t *details;				//details needed for scheduled work

};

/*-------------------End of Data types -------------------*/



/* ------------------ Functions --------------------------*/
/*Returns information extracted from UDP packet
* The parameter should point to the effective data in the packet
*/
PacketData_t *getPacketData(unsigned char *);



/* This function registers a new client accros the NAT traversal server
*	@1	- public port
*	@2	- public IP address
*	@3	- data from client
* intoarce unul din codurile de eroare REGISTER_OK, REGISTER_NOT_OK, INVALID_ID	
*/
int addClient(int, int, PacketData_t *);

/* sterge client
* intoarce UNREGISTER_OK, UNREGISTER_NOT_OK	
*/
int deleteClient(int);


/*sterge pe toti .. la iesire*/
void deleteAllClients(void);

/*clID
*1 = exista
*0 = nu exista
*/
int clientExists(int);


/*
1 - real port
2 - real Ip
3 - date din pachet
*/
static void processPacketData(int , int , PacketData_t *);

/*
trimite date raspuns catre client
1 - portDest
2 - ip dest
3 - cod raspuns
4 - packetData
*/
static void sendDataToClient(int, int, int, PacketData_t *);

/* obtain client details
1 - clientID
2 - return value
On success returns PacketData structure containing client's details
*/
PacketData_t *GetClientEndpoints(int , int *)

/*-------------------End of Functions --------------------*/

#endif
